package com.nartosoft.tubuloader;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.net.URL;
import java.util.List;

import javax.activation.MimetypesFileTypeMap;

import com.google.gdata.client.youtube.YouTubeService;
import com.google.gdata.data.media.MediaFileSource;
import com.google.gdata.data.media.mediarss.MediaCategory;
import com.google.gdata.data.media.mediarss.MediaDescription;
import com.google.gdata.data.media.mediarss.MediaKeywords;
import com.google.gdata.data.media.mediarss.MediaTitle;
import com.google.gdata.data.youtube.VideoEntry;
import com.google.gdata.data.youtube.YouTubeMediaGroup;
import com.google.gdata.data.youtube.YouTubeNamespace;

public class Tubuloader {

	private final EventDispatcher events;
	private Configuration options = null;

	public Tubuloader(EventDispatcher events) {
		this.events = events;
	}

	/**
	 * Uploads all files specified in fileNames.
	 * 
	 * @throws IOException
	 */
	public void uploadFiles(List<String> fileNames, Configuration options)
			throws IOException {
		this.options = options;
	    List<Tubuload> tubuloads = TubuloaderUI.openTubuloaderDialog(fileNames);
	    if (tubuloads.isEmpty()) {
	        events.notifyError("upload canceled by user");
	        return; 
	    }
	    else {
	        for (Tubuload tubuload : tubuloads) {
	        	uploadFile(tubuload);
	        }
	    }
		events.notifyAllDone();
	}

	/**
	 * Uploads the specified file to YouTube and writes the resulting url (or
	 * error message) to the EventWriter.
	 */
	private void uploadFile(Tubuload tubuload) throws IOException {
		String tmpFileName = tubuload.getFilename();
		File file = new File(tmpFileName);
		String fileToUpload = tmpFileName;

		// do some checks if file is valid
		if (file.isDirectory() || !file.exists()) {
			events.notifyError("invalid file: " + tmpFileName);
			return;
		}

		if (file.length() > options.getMaxFileSize()) {
			events.notifyError("file too big: " + tmpFileName);
			return;
		}
		if (fileToUpload != null) {
			doUpload(tubuload);
		} else {
			events.notifyError("fileToUpload is null");
		}
	}

	private void doUpload(Tubuload tubuload) {
		try {
			File file = new File(tubuload.getFilename());
			YouTubeService service = new YouTubeService(options.getClientID(),options.getDeveloperID());
			service.setUserCredentials(options.getUser(), options.getPassword());
			VideoEntry newEntry = new VideoEntry();
			//newEntry.setGeoCoordinates(new GeoRssWhere(37.0, -122.0));
			// alternatively, one could specify just a descriptive string
			//newEntry.setLocation("Vienna, Austria");

			YouTubeMediaGroup mg = newEntry.getOrCreateMediaGroup();

			mg.addCategory(new MediaCategory(YouTubeNamespace.CATEGORY_SCHEME,tubuload.getCategory().getValue()));
			mg.addCategory(new MediaCategory(YouTubeNamespace.DEVELOPER_TAG_SCHEME, "Tubuloader"));
			mg.setPrivate(!tubuload.isPublic());
			mg.setTitle(new MediaTitle());
			mg.getTitle().setPlainTextContent(tubuload.getTitle());
			mg.setKeywords(new MediaKeywords());
			String[] tags = tubuload.getTags().split(" ");
			mg.getKeywords().addKeywords(Arrays.asList(tags));
			mg.setDescription(new MediaDescription());
			mg.getDescription().setPlainTextContent(tubuload.getDescription());
			String mimetype = new MimetypesFileTypeMap().getContentType(file)
					.toString();
			MediaFileSource ms = new MediaFileSource(file, mimetype);
			newEntry.setMediaSource(ms);
			VideoEntry createdEntry = service.insert(new URL(options
					.getUploadURL()), newEntry);
			String link = createdEntry.getId();
			int pos = link.lastIndexOf("/");
			events.notifyUpload(file.getAbsolutePath(),"http://www.youtube.com/watch?v=" + link.substring(pos + 1));
		} catch (Exception e) {
			e.printStackTrace();
			events.notifyError("exception uploadFile: " + e.getMessage());
			return;
		}
	}

}